home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * CBspEval.c - Bezier curves handling routines - evaluation routines. *
- *******************************************************************************
- * Written by Gershon Elber, Mar. 90. *
- ******************************************************************************/
-
- #include <ctype.h>
- #include <stdio.h>
- #include <string.h>
- #include "cagd_loc.h"
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Assumes Vec holds control points for scalar Bspline curve of order Order M
- * length Len and knot vector KnotVector. M
- * Evaluates and returns that curve value at parameter value t. M
- * Vec is incremented by VecInc (usually by 1) after each iteration. M
- * *
- * PARAMETERS: M
- * Vec: Coefficents of a scalar Bspline univariate function. M
- * VecInc: Step to move along Vec. M
- * KnotVector: Knot vector of associated geoemtry. M
- * Order: Order of associated geometry. M
- * Len: Length of control vector. M
- * Periodic: If this geometry is Periodic. M
- * t: Parameter value where to evaluate the curve. M
- * *
- * RETURN VALUE: M
- * CagdRType: Geometry's value at parameter value t. M
- * *
- * KEYWORDS: M
- * BspCrvEvalVecAtParam, evaluation M
- *****************************************************************************/
- CagdRType BspCrvEvalVecAtParam(CagdRType *Vec,
- int VecInc,
- CagdRType *KnotVector,
- int Order,
- int Len,
- CagdBType Periodic,
- CagdRType t)
- {
- int i, IndexFirst;
- CagdRType
- R = 0.0,
- *BasisFunc = BspCrvCoxDeBoorBasis(KnotVector, Order,
- Len + (Periodic ? Order - 1 : 0),
- t, &IndexFirst);
-
- if (VecInc == 1) {
- for (i = 0; i < Order; i++)
- R += BasisFunc[i] * Vec[IndexFirst++ % Len];
- }
- else {
- int IndexFirstInc = IndexFirst;
-
- IndexFirstInc *= VecInc;
- for (i = 0; i < Order; i++) {
- R += BasisFunc[i] * Vec[IndexFirstInc];
- IndexFirstInc += VecInc;
- if (++IndexFirst >= Len) {
- IndexFirst -= Len;
- IndexFirstInc -= Len * VecInc;
- }
- }
- }
-
- return R;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns a pointer to a static data, holding the value of the curve at M
- * given parametric location t. The curve is assumed to be Bspline. M
- * Uses the Cox de Boor recursive algorithm. M
- * *
- * PARAMETERS: M
- * Crv: To evaluate at the given parametric location t. M
- * t: The parameter value at which the curve Crv is to be evaluated. M
- * *
- * RETURN VALUE: M
- * CagdRType *: A vector holding all the coefficients of all components M
- * of curve Crv's point type. If for example the curve's M
- * point type is P2, the W, X, and Y will be saved in the M
- * first three locations of the returned vector. The first M
- * location (index 0) of the returned vector is reserved for M
- * the rational coefficient W and XYZ always starts at second M
- * location of the returned vector (index 1). M
- * *
- * KEYWORDS: M
- * BspCrvEvalAtParam, evaluation M
- *****************************************************************************/
- CagdRType *BspCrvEvalAtParam(CagdCrvStruct *Crv, CagdRType t)
- {
- return BspCrvEvalCoxDeBoor(Crv, t);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Samples the curve at FineNess location equally spaced in the curve's M
- * parametric domain. M
- * Computes a refinement alpha matrix (If FineNess > 0), refines the curve M
- * and uses refined control polygon as the approximation to the curve. M
- * If FineNess == 0, Alpha matrix A is used instead. M
- * Returns the actual number of points in polyline (<= FineNess). M
- * Note this routine may be invoked with Bezier curves as well as Bspline. M
- * *
- * PARAMETERS: M
- * Crv: To approximate as a polyline. M
- * FineNess: Control on number of samples. M
- * Points: Where to put the resulting polyline. M
- * A: Optional alpha matrix for refinement. M
- * OptiLin: If TRUE, optimize linear curves. M
- * *
- * RETURN VALUE: M
- * int: The actual number of samples placed in Points. Always M
- * less than or eaul to FineNess. M
- * *
- * KEYWORDS: M
- * CagdCrvEvalToPolyline, conversion, refinement, evaluation M
- *****************************************************************************/
- int CagdCrvEvalToPolyline(CagdCrvStruct *Crv,
- int FineNess,
- CagdRType *Points[],
- BspKnotAlphaCoeffType *A,
- CagdBType OptiLin)
- {
- CagdBType
- IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
- int i, j, Count,
- Len = Crv -> Length,
- n = FineNess == 0 ? A -> RefLength : FineNess,
- Order = Crv -> Order,
- MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
-
- if (OptiLin && Crv -> Order == 2) { /* Simply copy the control polygon. */
- CagdRType
- **CrvPoints = Crv -> Points;
-
- for (Count = 0; Count < n && Count < Len; Count++)
- for (i = IsNotRational; i <= MaxCoord; i++)
- Points[i][Count] = CrvPoints[i][Count];
-
- if (Count < n &&
- CAGD_IS_BSPLINE_CRV(Crv) &&
- CAGD_IS_PERIODIC_CRV(Crv)) {
- for (i = IsNotRational; i <= MaxCoord; i++)
- Points[i][Count] = CrvPoints[i][0];
- Count++;
- }
-
- return Count;
- }
-
- if (FineNess > 0) {
- CagdRType *RefKV, Tmin, Tmax;
- int PeriodicLen = CAGD_CRV_PT_LST_LEN(Crv);
-
- /* Make sure we refine some place... */
- if (n <= PeriodicLen)
- CAGD_FATAL_ERROR(CAGD_ERR_REF_LESS_ORIG);
-
- CagdCrvDomain(Crv, &Tmin, &Tmax);
-
- RefKV = BspKnotPrepEquallySpaced(n - PeriodicLen, Tmin, Tmax);
-
- if (CAGD_IS_BEZIER_CRV(Crv)) {
- CagdRType
- *KV = BspKnotUniformOpen(Crv -> Length, Crv -> Order, NULL);
-
- A = BspKnotEvalAlphaCoefMerge(Order, KV, Len, RefKV, n - Len);
-
- IritFree((VoidPtr) KV);
- }
- else {
- A = BspKnotEvalAlphaCoefMerge(Order, Crv -> KnotVector,
- PeriodicLen, RefKV, n - PeriodicLen);
- }
-
- IritFree((VoidPtr) RefKV);
- }
-
- /* Compute the refined control polygon straight to destination Points. */
- for (j = IsNotRational; j <= MaxCoord; j++) {
- CagdRType
- *ROnePts = Points[j],
- *OnePts = Crv -> Points[j];
- for (i = 0; i < n; i++, ROnePts++)
- CAGD_ALPHA_BLEND(A, i, OnePts, Crv -> Length, ROnePts);
- }
-
- if (FineNess > 0)
- BspKnotFreeAlphaCoef(A);
-
- return n;
- }
-